package com.bjpowernode.mvc.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import com.bjpowernode.common.client.DfsClient;
import com.bjpowernode.common.constant.AppConstants;
import com.bjpowernode.common.constant.RedisKey;
import com.bjpowernode.common.enums.RespCode;
import com.bjpowernode.db.domain.HeaderImage;
import com.bjpowernode.db.domain.SysUser;
import com.bjpowernode.db.result.UserAccountResult;
import com.bjpowernode.mvc.model.dto.UserDTO;
import com.bjpowernode.mvc.model.dto.UserTokenDTO;
import com.bjpowernode.mvc.model.param.UserParam;
import com.bjpowernode.mvc.model.result.CommonResult;
import com.bjpowernode.mvc.model.vo.UserAccountResultVO;
import com.bjpowernode.mvc.model.vo.UserTokenVO;
import com.bjpowernode.mvc.service.inter.PayService;
import com.bjpowernode.mvc.service.inter.SmsService;
import com.bjpowernode.mvc.service.inter.UploadFileService;
import com.bjpowernode.mvc.service.inter.UserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/user")
public class UserController {

    private final UserService userService;
    private final PayService payService;
    private final UploadFileService uploadFileService;
    private final SmsService smsService;


    //@Validated的作用，先验证UserParam对象中的参数是否符合要求，符合要求再执行Controller，不符合要求则抛出异常

    /**
     * 注册账号
     *
     * @param userParam
     * @return
     */
    @PostMapping("/register")
    public CommonResult userRegister(@RequestBody @Validated UserParam userParam) {

        //1.验证短信验证码
        boolean checkCode = userService.checkSmsCode(AppConstants.ACTION_REGISTER, userParam.getPhone(), userParam.getCode());

        if (!checkCode) {
            return CommonResult.warn(RespCode.SMS_CODE_INVALID);
        }

        //2、注册用户
        UserDTO userDTO = new UserDTO();
        userDTO.setPassword(userParam.getPassword());
        userDTO.setPhone(userParam.getPhone());
        boolean registerResult = userService.registerUser(userDTO);
        return registerResult ? CommonResult.ok() : CommonResult.warn();
    }

    /**
     * 登录获取token
     * 控制器方法返回值CommonResult --> Jackson工具库的ObjectMapper类转为json格式字符串
     * --> 然后使用HttpServletResponse输出给前端
     *
     * @param userParam
     * @param request
     * @return
     */
    //@Validated注解用于触发参数验证
    @PostMapping(value = "/access/token")
    public CommonResult accessToken(@RequestBody @Validated UserParam userParam,
                                    HttpServletRequest request
    ) {
        //1.验证短信验证码
        boolean checkCode = userService.checkSmsCode(AppConstants.ACTION_LOGIN, userParam.getPhone(), userParam.getCode());
        if (!checkCode) {
            return CommonResult.warn(RespCode.SMS_CODE_INVALID);
        }

        //2.登录
        SysUser sysUser = userService.userLogin(userParam.getPhone(), userParam.getPassword(), request.getRemoteHost());

        if (sysUser == null) {
            return CommonResult.warn(RespCode.PHONE_PASSWORD_INVALID);
        }

        //3.生成token，存储token
        String token = userService.createToken(sysUser);

        //4.如果saved为真，则表示登录成功，返回数据给前端
        if (token != null) {
            //删除登录的短信验证码
            smsService.removeSmsCode(RedisKey.SMS_CODE_LOGIN + userParam.getPhone() + ":" + userParam.getCode());
            Map<String, String> data = new HashMap<>();
            data.put("uid", String.valueOf(sysUser.getId()));
            data.put("token", token);
            data.put("name", sysUser.getName());
            data.put("phone", sysUser.getPhone());
            return CommonResult.ok(data);
        }

        //返回失败
        return CommonResult.warn();
    }

    /**
     * 实名认证
     * <p>
     * 使用map来接收前端传过来的简单参数
     *
     * @param uid
     * @param param
     * @return
     */
    @PostMapping(value = "/realname")
    public CommonResult realname(
            @RequestHeader("uid") Integer uid,
            @RequestBody Map<String, String> param,
            @RequestHeader("Authorization") String authorization
    ) {

        String name = param.get("name");
        String idCard = param.get("idCard");

        //1、判断请求参数是否正确
        //isNotBlank()  : 用于检查一个字符串是否为空白(空白的定义是null，"",不可见字符：如空格，制表符，换行符等)
        if (StrUtil.isNotBlank(name) && name.length() > 1 && IdcardUtil.isValidCard(idCard)) {

            //2、是否做过实名认证
            SysUser sysUser = userService.queryById(uid);
            if (sysUser == null) {
                //手机号没有被注册，请先进行注册
                return new CommonResult(RespCode.PHONE_USER_NOT_EXITS);
            }

            //3、实名认证不能重复认证
            //StrUtil.isBlank()检查一个字符串是否为空或只包含空白字符
            if (StrUtil.isNotBlank(sysUser.getName()) || StrUtil.isNotBlank(sysUser.getIdCard())) {
                //实名认证不能重复认证
                return new CommonResult(RespCode.REALNAME_NOT_DOUBLE);
            }
        } else {
            //请求参数错误
            return new CommonResult(RespCode.REQUEST_PARAM_ERR);
        }

        //4、实名认证
        String token = authorization.substring(7);
        boolean idCardAuth = userService.realname(uid, name, idCard, token);
        return idCardAuth ? CommonResult.ok(name) : CommonResult.warn(RespCode.REALNAME_ERR);
    }

    /**
     * 根据用户主键查询用户账号信息
     *
     * @param uid
     * @return
     */
    @GetMapping("/info")
    public CommonResult queryUserAccount(
            @RequestHeader("uid") Integer uid
    ) {

        //1、查询用户账户详情
        UserAccountResult userAccountResult = userService.queryUserAccountByUid(uid);
        if (userAccountResult != null) {
            //查询用户头像
            String httpUrl = "";
            HeaderImage headerImage = uploadFileService.queryByUid(uid);
            if (headerImage != null) {
                httpUrl = DfsClient.HTTP_URL + headerImage.getGroupName() + "/" + headerImage.getFileId();
                userAccountResult.setHeaderImage(httpUrl);
            }
        }

        //2、转为vo   属性一致
        UserAccountResultVO userAccountResultVO = BeanUtil.copyProperties(userAccountResult, UserAccountResultVO.class);
        return CommonResult.ok(userAccountResultVO);
    }

    /**
     * 用户支付完成后免登录返回用户中心
     *
     * @param uid
     * @param token
     * @return
     */
    @GetMapping("/autoLogin")
    public CommonResult autoLogin(@RequestParam("uid") Integer uid,
                                  @RequestParam("token") String token) {
        CommonResult commonResult = CommonResult.warn(RespCode.TOKEN_LOGIN_INVALID);
        if (uid != null && uid > 0 && StrUtil.isNotEmpty(token)) {
            boolean checkResult = payService.checkUidToken(uid, token);
            if (checkResult) {
                //1、登陆成功,获取登录信息
                UserTokenDTO userTokenDTO = userService.getLoginInfo(token);
                //2、转VO
                UserTokenVO userTokenVO = BeanUtil.copyProperties(userTokenDTO, UserTokenVO.class);
                commonResult = CommonResult.ok(userTokenVO);
            }
        }
        return commonResult;
    }

    //退出登录
    @GetMapping("/logout")
    public CommonResult logout(@RequestHeader("Authorization") String authorization) {
        if (StrUtil.isNotEmpty(authorization) && authorization.startsWith("Bearer")) {
            String token = authorization.substring(7);
            boolean result = userService.userLogout(token);
            if (result) {
                return CommonResult.ok();
            }
        }
        return CommonResult.warn(RespCode.FAIL);
    }


}
